<template>
  <el-drawer
    :title="title"
    v-model="visible"
    size="650px"
    :show-close="true"
    append-to-body
    destroy-on-close
	:close-on-click-modal="false"
  >
    <template #default>
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        class="drawer-form"
        label-width="100px"
		label-position="top"
      >
	  
	  <el-scrollbar >
	  	<div class="section-title">
	  	  <span class="title-form_primary">基础信息</span>
	  	</div>
	  
        <el-form-item label="所属类别" prop="categoryId">
          <el-tree-select
            v-model="formData.categoryId"
            :data="categories"
            placeholder="请选择类别"
            check-strictly
            :render-after-expand="false"
            :props="{
              label: 'name',
              value: 'id',
              children: 'children'
            }"
          />
        </el-form-item>
		<el-form-item label="参数名称" prop="name">
		  <el-input v-model="formData.name" placeholder="请输入参数名称" />
		</el-form-item>
        <el-form-item label="参数标识" prop="code">
          <el-input v-model="formData.code" placeholder="请输入参数标识" />
        </el-form-item>
        <el-form-item label="参数描述" prop="description">
          <el-input 
            v-model="formData.description" 
            type="textarea" 
            :rows="3"
            placeholder="请输入参数描述" 
          />
        </el-form-item>
		
		<el-form-item label="排序" prop="sort">
		  <el-input-number v-model="formData.sort" :min="0" />
		</el-form-item>
		<div class="section-title">
		  <span class="title-form_primary">参数字段</span>
          <el-button type="primary" link @click="addParamDefinition">
            <el-icon><Plus /></el-icon>添加字段
          </el-button>
		</div>
		
	<div class="param-model-content">
		
		
     <draggable
       v-model="paramDefinitions"
       :animation="150"
       handle=".drag-handle"
       item-key="identifier"
       :component-data="{
         tag: 'div',
         type: 'transition-group',
         name: !drag ? 'flip-list' : null
       }"
       @start="drag = true"
       @end="drag = false"
     >
       <template #item="{ element: row, index }">
         <div class="param-model-content-row">
           <el-button 
             class="drag-handle" 
             link
           >
             <el-icon><Rank /></el-icon>
           </el-button>
           <div class="param-info">
             <div class="param-name">{{ row.name }}</div>
             <div class="param-detail">
               <span>标识符: {{ row.identifier }}</span>
               <span>类型: {{ row.dataType.type }}</span>
               <span>读写: {{ row.accessMode === 'r' ? '只读' : '读写' }}</span>
               <el-tag :type="row.required ? 'success' : 'info'" size="small">
                 {{ row.required ? '必选' : '可选' }}
               </el-tag>
             </div>
           </div>
           <div class="param-actions">
             <el-button type="primary" link @click="handleEditParam(index,row)">
               <el-icon><Edit /></el-icon>编辑
             </el-button>
             <el-button type="danger" link @click="removeParamDefinition(index)">
               <el-icon><Delete /></el-icon>删除
             </el-button>
           </div>
         </div>
       </template>
     </draggable>
     <div v-if="paramDefinitions.length === 0" class="empty-tip">
       暂无参数，请点击上方"添加参数"按钮添加
     </div>
   </div>
   </el-scrollbar>
      </el-form>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="handleCloseDrawer">取 消</el-button>
      </div>
    </template>
  </el-drawer>

  <param-definition-dialog
	v-if="paramDialogVisible"
	:index="fieldIndex"
	:visible="paramDialogVisible"
    :title="dialogTitle"
    :param="tempParamDefinitions"
    @success="handleParamDialogSuccess"
	@closed="handleParamDialogClosed"
  />
</template>

<script setup lang="ts">
import { ref, reactive, watch, computed } from 'vue';
import type { FormInstance } from 'element-plus';
import { ElMessage } from 'element-plus';
import type { ParamModelVO, ParamModelForm, ParamModelCategoryVO, ParamDefinition } from '@/api/biz/parammodel';
import ParamModelAPI from '@/api/biz/parammodel';
import { Plus, Delete, Edit, Rank } from '@element-plus/icons-vue';
import draggable from 'vuedraggable';
import ParamDefinitionDialog from './ParamDefinitionDialog.vue';

const props = defineProps({
  modelValue: {
    type: Boolean,
    required: true
  },
  title: {
    type: String,
    required: true
  },
  model: {
    type: Object as () => any,
    required: true
  },
  categories: {
    type: Array as () => ParamModelCategoryVO[],
    required: true
  }
});

const emit = defineEmits(['update:modelValue', 'success']);
const paramDefinitions = ref<ParamDefinition[]>([]);
const visible = ref(false);
const formRef = ref<FormInstance>();
const formData = reactive<ParamModelForm>({
  id: '',
  categoryId: '',
  code: '',
  name: '',
  description: '',
  content: '',
  sort: 0
});

const rules = {
  categoryId: [
    { required: true, message: '请选择所属类别', trigger: 'change' }
  ],
  code: [
    { required: true, message: '请输入参数标识', trigger: 'blur' },
    { pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '标识符必须以字母开头，只能包含字母、数字和下划线', trigger: 'blur' }
  ],
  name: [
    { required: true, message: '请输入参数名称', trigger: 'blur' },
    { min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
  ],
  description: [
    { required: false }
  ],
  sort: [
    { required: false }
  ]
};

watch(() => props.modelValue, (val) => {
  visible.value = val;
});

watch(() => visible.value, (val) => {
  emit('update:modelValue', val);
});

watch(
  () => props.model,
  (val) => {
    Object.assign(formData, val);
    // 解析 content 字符串为参数定义数组
    if (formData?.content) {
      try {
        const content = JSON.parse(val.content);
        paramDefinitions.value.push(...content);
      } catch (e) {
        console.error('解析参数定义失败:', e);
        ElMessage.error('参数定义格式错误');
      }
    } else {
      paramDefinitions.value = [];
    }
  },
  { immediate: true, deep: true }
);

const createDefaultParam = (): ParamDefinition => ({
  identifier: '',
  name: '',
  accessMode: 'rw',
  required: false,
  dataType: {
    type: 'text',
    specs: {}
  },
  defaultValue: ''
});

const tempParamDefinitions = ref<ParamDefinition>({
  identifier: '',
  name: '',
  accessMode: 'rw',
  required: false,
  dataType: {
    type: 'text',
    specs: {}
  },
  defaultValue: ''
});

const addParamDefinition = () => {
	fieldIndex.value=-1;
	tempParamDefinitions.value = {
		identifier: '',
		name: '',
		accessMode: 'rw',
		required: false,
		dataType: {
		  type: 'text',
		  specs: {}
		},
		defaultValue: ''
	};
	dialogTitle.value="新增字段";
	paramDialogVisible.value = true;
};

const removeParamDefinition = (index: number) => {
  ElMessageBox.confirm('确认删除该参数吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    paramDefinitions.value.splice(index, 1);
	formData.content = JSON.stringify(paramDefinitions.value);
    ElMessage.success('删除成功');
  }).catch(() => {});
};


const handleTypeChange = (_type: string, index: number) => {
  paramDefinitions.value[index].dataType.specs = {};
  paramDefinitions.value[index].defaultValue = '';
};

const getDefaultValuePlaceholder = (type: string) => {
  switch (type) {
    case 'int':
    case 'float':
    case 'double':
      return '请输入数字';
    case 'text':
      return '请输入文本';
    case 'date':
      return '请输入UTC毫秒时间戳';
    case 'bool':
      return '请输入0或1';
    case 'enum':
      return '请输入枚举值';
    case 'array':
    case 'struct':
      return '请输入JSON格式数据';
    default:
      return '';
  }
};

const paramDialogVisible = ref(false);
const fieldIndex = ref<number>(0);
const dialogTitle = ref<string>("");

const handleEditParam = (index: number,data:ParamDefinition) => {
	fieldIndex.value=index;
	tempParamDefinitions.value = data;
	dialogTitle.value="编辑字段";
	paramDialogVisible.value = true;
};

const handleParamDialogSuccess = (index:number,params: ParamDefinition) => {
  try {
    if (index > -1) {
      paramDefinitions.value[index] = params;
    } else {
      paramDefinitions.value.push(params);
    }
    formData.content = JSON.stringify(paramDefinitions.value);
	console.log(formData.content);
	console.log(paramDefinitions.value);
  } catch (e:any) {
    ElMessage.error(e.message);
  }
};

const handleParamDialogClosed=()=>{
	paramDialogVisible.value = false;
	tempParamDefinitions.value = {
		identifier: '',
		name: '',
		accessMode: 'rw',
		required: false,
		dataType: {
		  type: 'text',
		  specs: {}
		},
		defaultValue: ''
	}
}

const submitForm = async () => {
  if (!formRef.value) return;
  
  try {
    await formRef.value.validate();
    // const submitData = { ...formData };
    // if (!submitData.description) {
    //   delete submitData.description;
    // }
    // if (submitData.sort === undefined || submitData.sort === null) {
    //   delete submitData.sort;
    // }
    //validateParamDefinition(paramDefinitions);
   // submitData.content = JSON.stringify(paramDefinitions.value, null, 2);
	await ParamModelAPI.saveModel(formData);
    ElMessage.success('保存成功');
    handleCloseDrawer();
    emit('success');
  } catch (error: any) {
    ElMessage.error(error.message);
  }
};

const resetForm = () => {
  formRef.value?.resetFields();
  formRef.value?.clearValidate();
  formData.id = '';
  formData.categoryId = '';
  formData.code = '';
  formData.name = '';
  formData.description = '';
  formData.content = '';
  formData.sort = 0;
  paramDefinitions.value = [];  // 重置参数定义数组
};

function handleCloseDrawer() {
  visible.value = false;
  resetForm();
}

// const validateParamDefinition = (params: ParamDefinition[]) => {
// };

const drag = ref(false);
</script>

<style lang="scss" scoped>
.drawer-form {
  padding: 20px;
  height: calc(100vh - 130px);
  overflow-y: auto;
}

:deep(.el-drawer__header) {
  margin-bottom: 0;
  padding: 16px 20px;
  border-bottom: 1px solid var(--el-border-color-light);
}

:deep(.el-drawer__footer) {
  padding: 16px 20px;
  border-top: 1px solid var(--el-border-color-light);
  width: 100%;
}

:deep(.el-drawer__body) {
  padding: 0;
  height: calc(100% - 130px);
  overflow: hidden;
}

.dialog-footer {
  text-align: right;
}

.param-definition-form {
  padding: 16px;
  background-color: var(--el-fill-color-light);
  border-radius: 4px;

  :deep(.el-form-item) {
    margin-bottom: 18px;
  }
}

.param-definition-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding: 0 16px;
}

.param-definition-item {
  margin-bottom: 24px;
  border: 1px solid var(--el-border-color-light);
  border-radius: 4px;
}

.param-definition-item-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background-color: var(--el-fill-color);
  border-bottom: 1px solid var(--el-border-color-light);
}

.title-form_primary {
    font-style: normal;
    font-weight: 500;
    font-size: 14px;
    color: #1f2329;
    position: relative;
    padding-left: 5px;
}
.title-form_primary:before {
  content: "";
  width: 2px;
  height: 14px;
  background: var(--el-color-primary);
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0;
}

.param-dialog-content {
  max-height: calc(80vh - 150px);
  overflow-y: auto;
  padding: 0 20px;
}

.param-dialog-header {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 16px;
}

.section-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.param-model-content {
  padding: 16px;
  background: var(--el-fill-color-light);
  border-radius: 4px;
}

.param-model-content-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 8px;
  margin-bottom: 8px;
  background: var(--el-bg-color);
  border: 1px solid var(--el-border-color-lighter);
  border-radius: 4px;
  transition: all 0.3s;
  
  &:hover {
    border-color: var(--el-border-color);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  }
}

.param-info {
  flex: 1;
}

.param-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--el-text-color-primary);
  margin-bottom: 4px;
}

.param-detail {
  display: flex;
  align-items: center;
  gap: 16px;
  color: var(--el-text-color-secondary);
  font-size: 13px;
}

.param-actions {
  display: flex;
  gap: 8px;
}

.empty-tip {
  text-align: center;
  color: var(--el-text-color-secondary);
  padding: 32px 0;
}

.drag-handle {
  cursor: move;
  margin-right: 8px;
  color: var(--el-text-color-secondary);
  
  &:hover {
    color: var(--el-text-color-primary);
  }
}

.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
</style> 